home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Source Code
/
Libraries
/
MacPNG Library 1.02
/
pngMacSrc 1.02
/
ReadPNG.c
< prev
Wrap
C/C++ Source or Header
|
1995-10-26
|
5KB
|
195 lines
#include <stdio.h>
#include <stdlib.h>
#include "png.h"
// Requires: libpng, zlib, ANSI (4i) C lib's
#include <Files.h>
#include <Memory.h>
PicHandle ReadPGN(FSSpec *sfFilePtr)
{ OSErr err = noErr;
short savedVol;
Str31 name;
png_struct read_ptr;
png_info info_ptr;
png_info end_info;
FILE *fpin;
png_byte *row_buf;
png_uint_32 rowbytes;
png_uint_32 y, x;
int channels, num_pass, pass;
PicHandle myPic = nil;
BlockMoveData((Ptr)(sfFilePtr.name), (Ptr)name, sizeof(Str31));
err = GetVol(0, &savedVol);
if (err == noErr)
{
err = HSetVol(0, sfFilePtr->vRefNum, sfFilePtr->parID);
if (err == noErr)
{
p2cstr(name);
row_buf = (png_byte *)0;
fpin = fopen((char *) name, "rb");
if (!fpin) {
// fprintf(STDERR, "Could not find input file %s\n", inname);
return -1;
}
if (setjmp(read_ptr.jmpbuf)) {
// fprintf(STDERR, "libpng read error\n");
fclose(fpin);
return -2;
}
png_read_init(&read_ptr);
png_info_init(&info_ptr);
png_init_io(&read_ptr, fpin);
png_read_info(&read_ptr, &info_ptr);
#if OutputInfo /* RMF */
fprintf(STDERR, "%s, Width = %d, Height = %d, Depth = %d\n",
inname, info_ptr.width, info_ptr.height, info_ptr.bit_depth);
fprintf(STDERR, "Color type = %d, interlace_type = %d\n",
info_ptr.color_type, info_ptr.interlace_type);
#endif
if ((info_ptr.color_type & 3) == PNG_COLOR_MASK_COLOR)
channels = 3;
else channels = 1;
if (info_ptr.color_type & PNG_COLOR_MASK_ALPHA)
channels++;
rowbytes = ((info_ptr.width * info_ptr.bit_depth * channels + 7) >> 3);
row_buf = (png_byte *)malloc((size_t)rowbytes);
if (!row_buf) {
fprintf(STDERR, "no memory to allocate row buffer\n");
png_read_destroy(&read_ptr, &info_ptr, (png_info *)0);
fclose(fpin);
return -3;
}
if (info_ptr.interlace_type) {
num_pass = png_set_interlace_handling(&read_ptr);
} else {
num_pass = 1;
}
for (pass = 0; pass < num_pass; pass++)
{
for (y = 0; y < info_ptr.height; y++)
{
png_read_rows(&read_ptr, &row_buf, (png_byte **)0, 1); // Read one row of image data
}
}
png_read_end(&read_ptr, &end_info);
png_read_destroy(&read_ptr, &info_ptr, &end_info);
fclose(fpin);
x = info_ptr.width;
y = info_ptr.height;
if (info_ptr.bit_depth == 24) {
rowbytes = (x * 4L); // Make Multiple of 4 bytes (32bit RGB image)
} else {
ByteScanLine = (((x * (unsigned long) info_ptr.bit_depth) + 7L) / 8L); /* Make Multiple of byte */
}
// info_ptr.color_type =
// PNG_COLOR_TYPE_PALETTE
// PNG_COLOR_TYPE_RGB
// PNG_COLOR_TYPE_GRAY
// PNG_COLOR_TYPE_RGB_ALPHA
// PNG_COLOR_TYPE_GRAY_ALPHA
// Black & White Image
if (info_ptr.bit_depth == 1) {
BitMap theBits;
theBits.baseAddr = (Ptr) row_buf; // Set up new BitMap
theBits.rowBytes = rowbytes; // width of image
SetRect(&(theBits.bounds), 0, 0, x, y);
myPic = MakePictFromBW(&theBits); // create a PicHandle from B&W BitMap
// Cleanup and Exit.
} else {
CTabHandle macCtabHandle = nil;// Color Table for 2, 4, 8 bit images
PixMap srcBits;
if (info_ptr.bit_depth >= 2 && info_ptr.bit_depth <= 8) {
if (info_ptr.valid & PNG_INFO_PLTE) {
info_ptr.palette;
info_ptr.num_palette;
macCtabHandle = nil; // Get the color table...
}
}
// See: QuickDraw.h
// Setup PixMap data structure:
srcBits.baseAddr = row_buf; // ptr to the Pixcell data
// offset to next scan line
srcBits.rowBytes = rowbytes | 0x8000; // pixmap (4, 8, 16 or 24/32bit image)
srcBits.bounds.top = 0; // encloses bitmap
srcBits.bounds.left = 0;
srcBits.bounds.bottom = y;
srcBits.bounds.right = x;
srcBits.pmVersion = 0; // pixMap version number
srcBits.packType = 1; // defines packing format: 1 = direct
srcBits.packSize = 0L; // length of pixel data
srcBits.hRes = 0x480000; // 72dpi fixed point
srcBits.vRes = 0x480000; // vert. resolution (ppi)
srcBits.planeBytes = 0L; // offset to next plane
srcBits.pmTable = macCtabHandle; // color map for this pixMap
srcBits.pmReserved = 0;
if (info_ptr.bit_depth == 24) { // RGB data 24bit color, no Color Table
srcBits.pixelType = RGBDirect;
srcBits.pixelSize = 32; // # bits in pixel
srcBits.cmpCount = 3; // # components in pixel (R,G,B)
srcBits.cmpSize = 8; // # bits per component (3 * 8) =
// 24bits + 8bits pad = 32 bits
} else {
// Else: 4bit or 8bit color image
srcBits.pixelType = 0;
srcBits.pixelSize = info_ptr.bit_depth; // # bits in pixel
srcBits.cmpCount = 1; // # components in pixel
srcBits.cmpSize = info_ptr.bit_depth; // # bits per component
}
myPic = CreatePICT2( &srcBits, &srcBits.bounds, &srcBits.bounds, ditherCopy);
if (srcBits.pmTable) DisposHandle((Handle) srcBits.pmTable); // Free Color table allocated
}
/*------------ */
free(row_buf);
SetVol(0, savedVol);
return myPic;
} // End readPNG()